package com.xiaoshuidi.cloud.module.report.xxljob;

import com.xiaoshuidi.cloud.framework.tenant.core.aop.TenantIgnore;
import com.xiaoshuidi.cloud.framework.tenant.core.job.TenantJob;
import com.xiaoshuidi.cloud.module.report.constant.ContractNodeEnum;
import com.xiaoshuidi.cloud.module.report.constant.PayWayEnum;
import com.xiaoshuidi.cloud.module.report.constant.PublicUseConstant;
import com.xiaoshuidi.cloud.module.report.dal.DO.ContractOrderFeesDO;
import com.xiaoshuidi.cloud.module.report.dal.DO.ContractRentorderDO;
import com.xiaoshuidi.cloud.module.report.dal.DO.ContractRoomDO;
import com.xiaoshuidi.cloud.module.report.dal.DO.RoomHouseDO;
import com.xiaoshuidi.cloud.module.report.dal.DO.report.ReportPaymentDetailsDO;
import com.xiaoshuidi.cloud.module.report.dal.mapper.ContractOrderfeesMapper;
import com.xiaoshuidi.cloud.module.report.dal.mapper.ContractRentorderMapper;
import com.xiaoshuidi.cloud.module.report.dal.mapper.ContractRoomMapper;
import com.xiaoshuidi.cloud.module.report.dal.mapper.RoomHouseMapper;
import com.xiaoshuidi.cloud.module.report.service.ajreport.ReportPaymentDetailsService;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 处理收款明细数据每天7点
 */
@Component
@Slf4j
public class PaymentDetailsHandleJob {

    private static final Integer OUTFLOW = 1;

    @Resource
    private ReportPaymentDetailsService reportPaymentDetailsService;
    @Resource
    private RoomHouseMapper roomHouseMapper;
    @Resource
    private ContractRoomMapper contractRoomMapper;
    @Resource
    private ContractRentorderMapper contractRentorderMapper;
    @Resource
    private ContractOrderfeesMapper contractOrderfeesMapper;


    @XxlJob("paymentDetailsHandleJob")
    @TenantIgnore
    public void execute() {
        //获取所有未处理的收款明细
        List<ReportPaymentDetailsDO> unHandleList = reportPaymentDetailsService.selectUnHandle();
        if(CollectionUtils.isEmpty(unHandleList)){
            log.info("=====无未处理的收款明细========");
            return;
        }
        List<Long> roomIds = unHandleList.stream().map(ReportPaymentDetailsDO::getRoomId).collect(Collectors.toList());
        List<RoomHouseDO> houseList = roomHouseMapper.selectByIds(roomIds);
        for (ReportPaymentDetailsDO detailsDO : unHandleList) {
            //删除因手动修改已支付账单造成的重复数据
            reportPaymentDetailsService.updateRepeatByOrderId(detailsDO.getOrderId());
            //拼凑房源名称
            try {
                RoomHouseDO houseDO = houseList.stream().filter(e -> e.getId().equals(detailsDO.getRoomId())).findAny().orElse(null);
                if (houseDO == null) {
                    continue;
                }
                detailsDO.setIsConcentrated(houseDO.getIsConcentrated());
                detailsDO.setSpace(houseDO.getSpace());
                detailsDO.setIsWhole(houseDO.getIsWhole());
                if(ObjectUtils.isEmpty(detailsDO.getPayWay())){
                    //账单有些支付没有记支付方式
                    detailsDO.setPayWay("银行转账");
                }
                //集中式和分散式拼凑方法不一样
                StringBuilder houseName = new StringBuilder(houseDO.getBuildingNo()).append("栋");
                if (houseDO.getIsConcentrated()) {
                    //集中式 小区名-楼栋-房源名称   room_house.area - room_house.building_no栋 - room_house.name
                    detailsDO.setHouseResource(houseName.append(houseDO.getName()).toString());
                } else {
                    //分散式  小区名-楼栋-单元-房源名称 room_house.area - room_house.building_no栋 - room_house.unit_no单元 - room_house.name
                    detailsDO.setHouseResource(houseName.append(houseDO.getUnitNo()).append("单元").append(houseDO.getName()).toString());
                }
                //存合同编号和合同时间 合同总金额
                ContractRoomDO contractRoomDO = contractRoomMapper.selectById(detailsDO.getContractId());
                if(contractRoomDO==null){
                    log.error("====脏数据 有合同id:{},无合同",detailsDO.getContractId());
                    continue;
                }
                if(ContractNodeEnum.RENEWAL.getNode().equals(contractRoomDO.getContractNode())||
                        ContractNodeEnum.EXCHANGE.getNode().equals(contractRoomDO.getContractNode())){
                    //续租换租不算押金
                    detailsDO.setDeposit(BigDecimal.ZERO);
                }
                detailsDO.setArea(houseDO.getArea());
                detailsDO.setContractNo(contractRoomDO.getContractNo());
                detailsDO.setContractStartTime(contractRoomDO.getStartTime());
                detailsDO.setContractEndTime(contractRoomDO.getEndTime());
                BigDecimal totalRent = contractRoomDO.getTotalRent();
                BigDecimal property = contractRoomDO.getProperty() == null ? BigDecimal.ZERO :
                        contractRoomDO.getProperty();
//                BigDecimal deposit = contractRoomDO.getDeposit()==null?BigDecimal.ZERO: contractRoomDO.getDeposit();
                //产品说合同总金额不算押金
                detailsDO.setTotalAmount(totalRent.add(property));
                //TODO 累计已交租金 支付周期
                BigDecimal accRent =
                        contractRentorderMapper.selectTotalRentByContractIdAndOrderId(detailsDO.getContractId(),
                                LocalDateTime.now(), detailsDO.getOrderId());
                //原有逻辑不算入杂费优化
               /* if (accRent.compareTo(BigDecimal.ZERO) <= 0) {
                    accRent = contractRentorderMapper.selectTotalRentByContractIdAndPayed(detailsDO.getContractId(),
                            LocalDateTime.now());
                }*/
                detailsDO.setTotalRent(accRent);
                //本机缴纳金额（含押金）,本机缴纳金额（不含押金）,优惠券金额
                ContractRentorderDO contractRentorderDO = contractRentorderMapper.selectById(detailsDO.getOrderId());
                //账单上的实付没有减去优惠券 且续租时 实付包含结转的押金，这种不属于实付 需扣减
                BigDecimal orderAmount =
                        detailsDO.getOrderAmount().subtract(contractRentorderDO.getDepositAmount()).add(detailsDO.getDeposit());
                detailsDO.setOrderAmount(orderAmount);
                detailsDO.setOrderAmountWithoutDeposit(orderAmount.subtract(detailsDO.getDeposit()));
                detailsDO.setCouponAmount(contractRentorderDO.getCouponDiscount());
                detailsDO.setPayPeriod(PayWayEnum.getValueByMonth(contractRoomDO.getPayMethodF()));
                //TODO 查询账单明细
                //根据合同账单id查询明细list 根据费项名称判断 具体费项类型
                List<ContractOrderFeesDO> contractOrderFeesDOS = contractOrderfeesMapper.selectByOrderId(detailsDO.getOrderId());
                BigDecimal waterFee=BigDecimal.ZERO;
                BigDecimal electricFee=BigDecimal.ZERO;
                BigDecimal repairFee=BigDecimal.ZERO;
                BigDecimal otherFee=BigDecimal.ZERO;
                for (ContractOrderFeesDO feesDO : contractOrderFeesDOS) {
                    if (OUTFLOW.equals(feesDO.getFlowType())) {
                        //流出取反
                        feesDO.setAmount(feesDO.getAmount().negate());
                        feesDO.setDiscountAmount(feesDO.getDiscountAmount().negate());
                    }
                    switch (feesDO.getFeeName()) {
                        case PublicUseConstant.COLD_WATER:
                            waterFee = waterFee.add(feesDO.getAmount());
                            break;
                        case PublicUseConstant.HOT_WATER:
                            waterFee = waterFee.add(feesDO.getAmount());
                            break;
                        case PublicUseConstant.ELECTRICITY:
                            electricFee = electricFee.add(feesDO.getAmount());
                            break;
                        case PublicUseConstant.REPAIR:
                            repairFee = repairFee.add(feesDO.getAmount());
                            break;
                        case PublicUseConstant.DEPOSIT:
                        case PublicUseConstant.RENT:
                            break;
                        default:
                            otherFee = otherFee.add(feesDO.getAmount());
                    }
                }
                detailsDO.setWaterFee(waterFee);
                detailsDO.setElectricFee(electricFee);
                detailsDO.setMaintenanceFee(repairFee);
                detailsDO.setOtherAmount(otherFee);
                detailsDO.setHandleFlag(1);
            } catch (Exception e) {
                log.error("========收款明细数据异常 contractId:{}",detailsDO.getContractId());
                e.printStackTrace();
            }
        }
        //批量修改 list
        reportPaymentDetailsService.updateBatch(unHandleList);
    }
}
